/**
 * Vue3 与 Vue2 的一些区别
 *
 * 1. 内部响应式原理不同
 * 2. 新增的
 *    1. 组合式API
 *    2. Teleport 组件
 *    3. Suspence 组件
 *    4. Fragments 片段 【组件是否可以有多个根元素】
 *    5. 新增了 emits 选项
 * 3. 全局 Vue API 被移除，改为使用应用实例
 * 4. 全局 API Treeshaking 【树摇】
 * 5. 组件上使用 v-model 的语法已修改
 * 6. 同一元素上 v-if 与 v-for 优先级的变化
 * 7. 移除了 $listeners 实例属性，现在没有被 emits 声明的事件也会添加到 $attrs 中。
 * 8. class 、style 已添加到 $attrs 中
 */

function mitt() {
  const obj = {};

  /**
   * {
   *    message: [callback],
   *    abcd: [callback]
   * }
   */
  const map = {};

  obj.on = function (eventName, callback) {
    // 要将 callback 给存起来
    if (map[eventName]) {
      // 存在，则将 callback 追加进去
      map[eventName].push(callback);
    } else {
      // 不存在，就新增成一个数组
      map[eventName] = [callback];
    }
  };

  obj.off = function (eventName) {
    delete map[eventName];
  };

  obj.emit = function (eventName, payload) {
    if (map[eventName]) {
      map[eventName].forEach((callback) => {
        callback(payload);
      });
    }
  };

  return obj;
}

// 创建 EventBus
const EventBus = mitt();

// 监听一个 message 事件
EventBus.on("message", () => {
  console.log("message 被触发了");
});
// 监听一个 abcd 事件
EventBus.on("abcd", (payload) => {
  console.log("abcd 被触发了", payload);
});

EventBus.emit("message");
// 'message 被触发了'
EventBus.emit("abcd", "张三");
// 'abcd 被触发了', '张三'

EventBus.emit("abcd");
// 'abcd 被触发了', undefined

EventBus.off("abcd");
EventBus.emit("abcd");
// 没有输出了
